/*
 * SkyBox.cpp
 *
 *      Author: Boboss
 */

#include "CSkyBox.h"

CSkyBox::CSkyBox() {
	_rotationInitiale = new osg::MatrixTransform();
	_rotationInitiale->setMatrix(osg::Matrix::rotate(osg::inDegrees(-90.0f),1.0,0.0,0.0));
}

osg::TextureCubeMap* CSkyBox::readCubeMap()
{
    osg::TextureCubeMap* cubemap = new osg::TextureCubeMap;
	    #define CUBEMAP_FILENAME(face) "./ressource/Cubemap_snow/" #face ".jpg"

	    osg::Image* imagePosX = osgDB::readImageFile(CUBEMAP_FILENAME(posx));
	    osg::Image* imageNegX = osgDB::readImageFile(CUBEMAP_FILENAME(negx));
	    osg::Image* imagePosY = osgDB::readImageFile(CUBEMAP_FILENAME(posy));
	    osg::Image* imageNegY = osgDB::readImageFile(CUBEMAP_FILENAME(negy));
	    osg::Image* imagePosZ = osgDB::readImageFile(CUBEMAP_FILENAME(posz));
	    osg::Image* imageNegZ = osgDB::readImageFile(CUBEMAP_FILENAME(negz));

	    if (imagePosX && imageNegX && imagePosY && imageNegY && imagePosZ && imageNegZ)
	    {
	        cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
	        cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);
	        cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
	        cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);
	        cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);
	        cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);

	        cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
	        cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
	        cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);

	        cubemap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
	        cubemap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	   }

	   return cubemap;
}

osg::Node* CSkyBox::createSkyBox()
{

	osg::StateSet* stateset = new osg::StateSet();

    osg::TexEnv* te = new osg::TexEnv;
    te->setMode(osg::TexEnv::REPLACE);
    stateset->setTextureAttributeAndModes(0, te, osg::StateAttribute::ON);

    osg::TexGen *tg = new osg::TexGen;
    tg->setMode(osg::TexGen::NORMAL_MAP);
    stateset->setTextureAttributeAndModes(0, tg, osg::StateAttribute::ON);

    osg::TexMat *tm = new osg::TexMat;
    stateset->setTextureAttribute(0, tm);

    osg::TextureCubeMap* skymap = readCubeMap();
    stateset->setTextureAttributeAndModes(0, skymap, osg::StateAttribute::ON);

    stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
    stateset->setMode( GL_CULL_FACE, osg::StateAttribute::OFF );

    // clear the depth to the far plane.
    osg::Depth* depth = new osg::Depth;
    depth->setFunction(osg::Depth::ALWAYS);
    depth->setRange(1.0,1.0);
    stateset->setAttributeAndModes(depth, osg::StateAttribute::ON );

    stateset->setRenderBinDetails(-1,"RenderBin");

    osg::Drawable* drawable = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),1));

    osg::Geode* geode = new osg::Geode;
    geode->setCullingActive(false);
	geode->setStateSet( stateset );
	geode->addDrawable(drawable);


    osg::Transform* transform = new MoveEarthySkyWithEyePointTransform;
	transform->setCullingActive(false);
	transform->addChild(geode);

	osg::ClearNode* clearNode = new osg::ClearNode;
//  clearNode->setRequiresClear(false);
    clearNode->setCullCallback(new TexMatCallback(*tm));
    clearNode->addChild(transform);

    _rotationInitiale->addChild(clearNode);

    return _rotationInitiale;
}

CSkyBox::~CSkyBox() {
	// TODO Auto-generated destructor stub
}


void CSkyBox::update(float angleVue, float phi)
{
	_rotationInitiale->setMatrix(osg::Matrix::rotate(osg::inDegrees(-90.0f)-phi,1.0,0.0,0.0));
	//_rotationInitiale->preMult(osg::Matrix::rotate(-phi,fabs(cos(angleVue)),-fabs(sin(angleVue)),0.0));
	_rotationInitiale->preMult(osg::Matrix::rotate(angleVue,0.0,0.0,1.0));
}
